package com.wk.cart.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.wk.cart.entity.Cart;
import com.wk.cart.interceptor.LoginInterceptor;
import com.wk.cart.service.CartService;
import com.wk.common.bean.UserInfo;
import com.wk.common.constant.RedisKey;
import com.wk.pms.entity.SkuInfo;
import com.wk.pms.feign.SkuInfoFeign;
import com.wk.pms.feign.SkuSaleAttrValueFeign;
import com.wk.sms.feign.SkuBoundsFeign;
import com.wk.wms.entity.WareSku;
import com.wk.wms.feign.WareSkuFeign;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class CartServiceImpl implements CartService {

    @Autowired
    private SkuInfoFeign skuInfoFeign;

    @Autowired
    private SkuSaleAttrValueFeign saleAttrValueFeign;

    @Autowired
    private SkuBoundsFeign skuBoundsFeign;

    @Autowired
    private WareSkuFeign wareSkuFeign;

    @Autowired
    private StringRedisTemplate redisTemplate;


    @Override
    public List<Cart> queryCarts() {

        //获取用户登录状态
        UserInfo userInfo = LoginInterceptor.getUserInfo();

        //查询未登录状态下的购物车
        String unLoginKey = RedisKey.CART_ITEM + userInfo.getUserKey();
        List<Object> cartJson = redisTemplate.boundHashOps(unLoginKey).values();

        List<Cart> unLoginCarts = null;

        if (CollectionUtils.isNotEmpty(cartJson)) {
            unLoginCarts = cartJson.stream().map(carts->{
                Cart cart = JSON.parseObject(carts.toString(), Cart.class);

                //查询商品当前实时价格
                String priceStr = redisTemplate.boundValueOps(RedisKey.CART_PRICE + cart.getSkuId()).get();
                cart.setCurrentPrice(new BigDecimal(priceStr));
                return cart;
            }).collect(Collectors.toList());
        }

        //如果用户未登录直接返回未登录状态的购物车
        if (userInfo.getId() == null) {
            return unLoginCarts;
        }

        //如果用户已登录需要将未登录状态的购物车合并到已登录状态的购物车 类似新增购物车操作

        //查询登录状态的购物车
        BoundHashOperations<String, Object, Object> loginHash = redisTemplate.boundHashOps(RedisKey.CART_ITEM + userInfo.getId());

        //判断是否存在未登录状态的购物车
        if (CollectionUtils.isNotEmpty(unLoginCarts)) {
            unLoginCarts.forEach(cart -> {

                String skuId = cart.getSkuId().toString();
                Integer count = cart.getCount();

                //登录状态的购物车包含未登录状态购物车中的商品则更新数量
                if (loginHash.hasKey(skuId)) {
                    cart = JSON.parseObject(loginHash.get(skuId).toString(), Cart.class);
                    cart.setCount(cart.getCount() + count);
                }

                //数量更新完成后再次放入缓存
                loginHash.put(skuId, JSON.toJSONString(cart));
            }) ;

            //商品同步到已登录状态的购物车后 删除未登录状态的购物车
            redisTemplate.delete(unLoginKey);
        }

        //查询登录状态的购物车
        return loginHash.values().stream().map(loginCartJson->{
            Cart cart = JSON.parseObject(loginCartJson.toString(), Cart.class);

            //查询商品当前实时价格
            String priceStr = redisTemplate.boundValueOps(RedisKey.CART_PRICE + cart.getSkuId()).get();
            cart.setCurrentPrice(new BigDecimal(priceStr));

            return cart;
        }).collect(Collectors.toList());

    }

    @Override
    public void updateCarts(Cart cart) {
        String key = getLoginStatus();

        //获取购物车对象
        BoundHashOperations<String, Object, Object> cartMap = redisTemplate.boundHashOps(key);

        String skuId = cart.getSkuId().toString();
        Integer count = cart.getCount();

        //判断更新对象是否存在购物车中
        if (cartMap.hasKey(skuId)) {
           cart = JSON.parseObject(cartMap.get(skuId).toString(), Cart.class);
           cart.setCount(count);
           cartMap.put(skuId, JSON.toJSONString(cart));
        }
    }

    @Override
    public void deleteCarts(Long skuId) {
        String key = getLoginStatus();
        redisTemplate.boundHashOps(key).delete(skuId.toString());
    }

    /**
     * 根据用户ID从Redis中获取购物车中的商品，再过滤出被选中的商品
     */
    @Override
    public List<Cart> queryCheckedCartByUserId(Long userId) {
        List<Object> cartListJson = redisTemplate.boundHashOps(RedisKey.CART_ITEM + userId).values();

        //购物车json集合遍历转换为对象后过滤checked==true的商品
        return cartListJson.stream().map(carts -> JSON.parseObject(carts.toString(), Cart.class)).filter(Cart::getCheck).collect(Collectors.toList());
    }


    @Override
    public void addCart(Cart cart) {
        String key = getLoginStatus();

        String skuId = cart.getSkuId().toString();

        //从Redis中获取购物车信息
        BoundHashOperations<String, Object, Object> cartHash = redisTemplate.boundHashOps(key);

        //记录新增购物车商品数量
        Integer count = cart.getCount();

        //购物车中已存在相同商品则更新数量
        if (cartHash.hasKey(skuId)) {
            //将Redis中对应的json转为对象
            cart = JSON.parseObject(cartHash.get(skuId).toString(), Cart.class);
            cart.setCount(cart.getCount()+count);
        } else {
            //不存在相同商品则新增商品到购物车
            cart = buildCart(cart);

            //存放商品当前价格 用于显示价格的变化
            redisTemplate.boundValueOps(RedisKey.CART_PRICE + skuId).set(cart.getPrice().toString());
        }

        //将处理完成的购物车对象转为json后重新放入缓存
        cartHash.put(skuId, JSON.toJSONString(cart));
    }


    /**
     * 构建购物车对象
     */
    private Cart buildCart(Cart cart) {
        Long skuId = cart.getSkuId();
        SkuInfo sku = skuInfoFeign.info(skuId).getData();
        if (sku == null) {
            return null;
        }
        //sku相关数据
        cart.setTitle(sku.getSkuTitle());
        cart.setPrice(sku.getPrice());
        cart.setDefaultImage(sku.getSkuDefaultImg());

        //销售信息
        cart.setSaleAttrValues(saleAttrValueFeign.queryBySkuId(skuId).getData());

        //营销信息
        cart.setSaleS(skuBoundsFeign.querySaleVoBySkuId(skuId).getData());

        //库存信息
        List<WareSku> wareSkus = wareSkuFeign.queryBySkuId(skuId).getData();
        if (CollectionUtils.isNotEmpty(wareSkus)) {
            cart.setStore(wareSkus.stream().anyMatch(ware->ware.getStock()>0));
        }

        //购物车中的商品默认选中
        cart.setCheck(true);

        return cart;
    }

    /**
     * 获取登录状态 已登录获取userId 未登录获取userKey
     */
    private String getLoginStatus() {
        String key = RedisKey.CART_ITEM;

        UserInfo userInfo = LoginInterceptor.getUserInfo();

        if(userInfo.getId()==null){
            key+=userInfo.getUserKey();
        }else {
            key+=userInfo.getId();
        }
        return key;
    }
}
